<template>
  <n-form
    ref="formRef"
    :model="form"
    :rules="formRules"
    :size="option.size"
    :disabled="option.disabled"
    :label-width="option.labelWidth"
    :label-align="option.labelAlign"
    :label-placement="option.labelPlacement"
    :require-mark-placement="option.requireMarkPlacement">
    <form-group
      v-if="option.group"
      v-model="form"
      :group="option.group"
      :cols="option.cols"
      :x-gap="option.xGap"
      :y-gap="option.yGap"
      :feedback-class="option.feedbackClass"
      :feedback-style="option.feedbackStyle"
      :accordion="option.groupAccordion" />
    <form-items
      v-else
      v-model="form"
      :items="option.items"
      :cols="option.cols"
      :x-gap="option.xGap"
      :y-gap="option.yGap"
      :feedback-class="option.feedbackClass"
      :feedback-style="option.feedbackStyle" />
  </n-form>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from "vue";
import { NForm } from "naive-ui";
import type { FormInst, FormItemRule, FormRules } from "naive-ui";
import FormGroup from "./FormGroup.vue";
import FormItems from "./FormItems.vue";
import type { NaiveFormItem, NaiveFormOption } from "./interface";
import type { RowData } from "@/_interface";

const form = defineModel<RowData>({ default: reactive({}) });
const props = defineProps<{ option: NaiveFormOption }>();

const formRef = ref<FormInst>();

const provider = (callback: (item: NaiveFormItem) => void) => {
  if (props.option.group) {
    props.option.group.forEach((groupItem) => {
      groupItem.items.forEach(callback);
    });
  } else {
    props.option.items?.forEach(callback);
  }
};
const formRules = computed<FormRules>(() => {
  const rules: Record<string, FormItemRule | FormItemRule[]> = {};
  provider((item) => {
    if (item.rules) rules[item.key] = item.rules;
  });
  return rules;
});

provider((item) => {
  if (item.value !== undefined) form.value[item.key] = item.value;
});
</script>
